package org.zlpt.contract.service;

import com.owlike.genson.Genson;
import org.hyperledger.fabric.contract.Context;
import org.hyperledger.fabric.contract.ContractInterface;
import org.hyperledger.fabric.contract.annotation.Transaction;
import org.hyperledger.fabric.shim.ChaincodeException;
import org.hyperledger.fabric.shim.ChaincodeStub;
import org.zlpt.entity.co.FapiaoCO;
import org.zlpt.entity.co.FapiaoOcrCO;
import org.zlpt.entity.co.WordsResultCO;
import org.zlpt.entity.co.FapiaoVerificationResultCO;
import org.zlpt.entity.co.CommodityVerificationResultCO;
import org.zlpt.entity.enums.DriverType;
import org.zlpt.entity.enums.PayerType;

import java.math.BigDecimal;

/**
 * @author sy
 * @version 1.0
 * @date 2023/4/25 14:47
 */
public final class TaxContract implements ContractInterface {
    private final Genson genson = new Genson();


    @Transaction(intent = Transaction.TYPE.EVALUATE)
    public FapiaoVerificationResultCO fapiaoVerification(final Context ctx, String fapiaoId) {

        ChaincodeStub stub = ctx.getStub();
        String keyPrefiexFapiaoId = FapiaoCO.formKey(Long.valueOf(fapiaoId));
        String fapiaoJSON = stub.getStringState(keyPrefiexFapiaoId);
        if (fapiaoJSON == null || fapiaoJSON.isEmpty()) {
            String errorMessage = String.format("Fapiao does not exist");
            System.out.println(errorMessage);
            throw new ChaincodeException(errorMessage);
        }
        FapiaoCO fapiaoCO = genson.deserialize(fapiaoJSON, FapiaoCO.class);
        String fapiaoNumber = fapiaoCO.getFapiaoNumber();
        FapiaoOcrCO fapiaoOcrCO = fapiaoCO.getFapiaoOcrCO();
        WordsResultCO wordsResult = fapiaoOcrCO.getWordsResult();

        int wordSize = wordsResult.getCommodityTaxRate().size();
        for (int i = 0; i < wordSize; i++) {
            String commodityTaxStr = wordsResult.getCommodityTax().get(i).getWord();

            BigDecimal commodityTax = new BigDecimal(commodityTaxStr.replace("%", "")).divide(new BigDecimal(100));

            BigDecimal caltax = TaxCompare(fapiaoCO.getPayerType() , fapiaoCO.getDriverType());







            verifyWord(caltax, commodityTax, reason , vail);





        }


        //与发票税率进行比较




        FapiaoVerificationResultCO fapiaoVerificationResultVO = new FapiaoVerificationResultCO();

        if(taxRate.compareTo(totalTaxRate) == 0){


            return fapiaoVerificationResultVO;

        }else if(taxRate.compareTo(totalTaxRate) == -1){

            BigDecimal differenceAmount = new BigDecimal(Double.toString(0.0));

            differenceAmount.add(totalTaxRate);
            differenceAmount.subtract(taxRate);

            fapiaoVerificationResultVO.setDifferenceAmount(differenceAmount);

            System.out.println("Fapiao" + fapiaoNumber);

            return fapiaoVerificationResultVO;
        }

        return null;

    }

    /**
     * 一个根据纳税人资质和是否含有驾驶员来计算税率的方法
     * @param payerType 纳税人资质（企业类型）
     * @param driverType 是否有驾驶员
     * @return 计算出的税率
     */
    public BigDecimal TaxCompare (PayerType payerType , DriverType driverType) {

        BigDecimal baseTaxRate = new BigDecimal(Double.toString(0.0));// 基础税率
        BigDecimal additionalTaxRate = new BigDecimal(Double.toString(0.0));// 额外税率
        //根据租赁信息进行税率计算
        if (driverType == DriverType.HAVE_DRIVER) {
            additionalTaxRate = payerType == PayerType.GENERAL_TAXPAYERS ?
                    additionalTaxRate.add(BigDecimal.valueOf(0.09))
                    : additionalTaxRate.add(BigDecimal.valueOf(0.0));
        }

        if (payerType == PayerType.GENERAL_TAXPAYERS
                && driverType == DriverType.ON_DRIVER) {
            baseTaxRate.add(BigDecimal.valueOf(0.13));
        } else {
            baseTaxRate.add(BigDecimal.valueOf(0.03));
        }
        BigDecimal totalTaxRate = new BigDecimal(Double.toString(0.0));
        totalTaxRate.add(baseTaxRate);
        totalTaxRate.add(additionalTaxRate);

        return totalTaxRate;

    }

    public CommodityVerificationResultCO verifyWord(BigDecimal verifiedTax, BigDecimal commodityTax, String commodityReason, Boolean valid) {

        CommodityVerificationResultCO commodityVerificationResultCO = new CommodityVerificationResultCO();

        commodityVerificationResultCO.setVerifiedTax(verifiedTax);

        commodityVerificationResultCO.setCommodityTax(commodityTax);

        commodityVerificationResultCO.setCommodityReason(commodityReason);

        commodityVerificationResultCO.setValid(valid);

        return commodityVerificationResultCO;

    }
}
